package com.ruoyi.order.service.impl;

import cn.hutool.core.io.FileUtil;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.WechatCustomerConfig;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MoneyUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.WeChatPayUrl;
import com.ruoyi.common.utils.tool.WechatPayUtil;
import com.ruoyi.common.utils.wechat.WxChatPayCommonUtil;
import com.ruoyi.merchant.domain.ImsYzzcSunGoods;
import com.ruoyi.merchant.service.IImsVehViolationService;
import com.ruoyi.merchant.service.IImsYzzcSunGoodsService;
import com.ruoyi.order.domain.*;
import com.ruoyi.order.domain.dto.AssignOrders;
import com.ruoyi.order.domain.dto.WxVhiceodrDto;
import com.ruoyi.order.domain.ex.OrderConstant;
import com.ruoyi.order.domain.ex.OrderException;
import com.ruoyi.order.domain.vo.SumQuantityVo;
import com.ruoyi.order.domain.vo.WxVhiceodrOeaiRcrVo;
import com.ruoyi.order.domain.vo.WxVhiceodrVo;
import com.ruoyi.order.mapper.WxVhiceodrMapper;
import com.ruoyi.order.mapper.WxVhiceodrOeaiRcrMapper;
import com.ruoyi.order.service.IWxVhiceodrService;
import com.ruoyi.system.domain.ImsVehMerUnit;
import com.ruoyi.system.service.IImsVehMerUnitService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.net.ssl.SSLContext;
import java.io.BufferedInputStream;
import java.math.BigDecimal;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 租车订单实例Service业务层处理
 *
 * @author ruoyi
 * @date 2024-08-29
 */
@Service
public class WxVhiceodrServiceImpl implements IWxVhiceodrService {

    @Autowired
    private WxVhiceodrMapper wxVhiceodrMapper;
    @Autowired
    private WxVhiceodrOeaiRcrMapper wxVhiceodrRecordMapper;
    @Autowired
    private WechatCustomerConfig wechatCustomerConfig;
    @Autowired
    private IImsYzzcSunGoodsService imsYzzcSunGoodsService;
    @Autowired
    private WxFormServiceImpl wxFormService;
    @Autowired
    private WxFormRecordServiceImpl wxFormRecordService;
    @Autowired
    private IImsVehMerUnitService imsVehCusUnitService;
    @Autowired
    private IImsVehViolationService imsVehViolationService;


    /**
     * 通过订单创建对应的表单
     *
     * @param wxVhiceodr 订单信息
     */
    private void createForm(WxVhiceodr wxVhiceodr) {
        ImsVehMerUnit imsVehMerUnitData = new ImsVehMerUnit();
        imsVehMerUnitData.setDeptId(wxVhiceodr.getDeptId());
        List<ImsVehMerUnit> imsVehMerUnitList = imsVehCusUnitService.selectImsVehCusUnitList(imsVehMerUnitData);
        ImsVehMerUnit imsVehMerUnit;
        if (imsVehMerUnitList.isEmpty()) {
            throw new RuntimeException("当前用户没有绑定指定表单，请联系管理员");
        } else {
            imsVehMerUnit = imsVehMerUnitList.get(0);
        }
        // 获取表单信息
        WxForm wxForm;
        // TODO: 需要添加收车表单的提成模版表单
        if (wxVhiceodr.getOrderType() == 0) {
            //创建租车提成表单
            wxForm = wxFormService.selectWxFormById((long) imsVehMerUnit.getRentalForm());
            // 通过表单模版创建保单记录
            WxFormRecord wxFormRecord = WxFormRecord.getWxFormRecord(wxVhiceodr, wxForm);
            wxFormRecordService.insertWxFormRecord(wxFormRecord);
            // 将送车提成的表单id放入到字段中
            wxVhiceodr.setPickFormId(wxFormRecord.getId());

            //创建收车提成表单
            wxForm = wxFormService.selectWxFormById((long) imsVehMerUnit.getCollectForm());
            wxFormRecord = WxFormRecord.getWxFormRecord(wxVhiceodr, wxForm);
            wxFormRecordService.insertWxFormRecord(wxFormRecord);
            wxVhiceodr.setReturnFormId(wxFormRecord.getId());
        } else if (wxVhiceodr.getOrderType() == 1) {

            wxForm = wxFormService.selectWxFormById((long) imsVehMerUnit.getCharterForm());
            // 通过表单模版创建保单记录
            WxFormRecord wxFormRecord = WxFormRecord.getWxFormRecord(wxVhiceodr, wxForm);
            wxFormRecordService.insertWxFormRecord(wxFormRecord);
            // 将包车提成的表单id放入到字段中
            wxVhiceodr.setPickFormId(wxFormRecord.getFormId());
        } else {
            throw new RuntimeException("非法的订单类型");
        }
        wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr);
    }



    /**
     * 查询租车订单实例
     *
     * @param orderNum 租车订单实例主键
     * @return 租车订单实例
     */
    @Override
    public WxVhiceodrVo selectWxVhiceodrByNum(String orderNum) {
        WxVhiceodrVo wxVhiceodrVo= wxVhiceodrMapper.selectWxVhiceodrByNum(orderNum);
        wxVhiceodrVo.setVehicleParams(new String[]{wxVhiceodrVo.getColour(), wxVhiceodrVo.getStructureStr(), wxVhiceodrVo.getGrarboxStr(), wxVhiceodrVo.getDisplacement(), wxVhiceodrVo.getBrandStr()});
        return wxVhiceodrVo;
    }

    /**
     * 查询租车订单实例列表
     *
     * @param wxVhiceodr 租车订单实例
     * @return 租车订单实例
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<WxVhiceodrVo> selectWxVhiceodrList(WxVhiceodrDto wxVhiceodr) {
        return wxVhiceodrMapper.selectWxVhiceodrList(wxVhiceodr);
    }

    @Override
    public List<WxVhiceodrVo> selectWechatOrderList(String wid, String status) {
        List<WxVhiceodrVo> list=wxVhiceodrMapper.selectWechatOrderList(wid, status);
        for (WxVhiceodrVo wxVhiceodr : list) {
            wxVhiceodr.setVehicleParams(new String[]{wxVhiceodr.getColour(), wxVhiceodr.getStructureStr(), wxVhiceodr.getGrarboxStr(), wxVhiceodr.getDisplacement(), wxVhiceodr.getBrandStr()});
        }
        return list;
    }

    /**
     * 新增租车订单实例
     *
     * @param wxVhiceodr 租车订单实例
     * @return 结果
     */
    @Override
    public int insertWxVhiceodr(WxVhiceodr wxVhiceodr) {
        wxVhiceodr.setCreateTime(DateUtils.getNowDate());
        return wxVhiceodrMapper.insertWxVhiceodr(wxVhiceodr);
    }

    /**
     * 修改租车订单实例
     *
     * @param wxVhiceodr 租车订单实例
     * @return 结果
     */
    @Override
    public int updateWxVhiceodr(WxVhiceodr wxVhiceodr) {
        return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr);
    }

    /**
     * 修改租车订单金额
     *
     * @param wxVhiceodr 租车订单金额
     * @return 结果
     */
    @Override
    public int editMoney(WxVhiceodr wxVhiceodr) {
        int i = wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr);
        WxVhiceodrDto vhiceodr = new WxVhiceodrDto();
        vhiceodr.setOrderNum(wxVhiceodr.getOrderNum());
        List<WxVhiceodrVo> wxVhiceodrs = wxVhiceodrMapper.selectWxVhiceodrList(vhiceodr);
        if (wxVhiceodrs != null && !wxVhiceodrs.isEmpty()) {
            for (WxVhiceodr wxvhiceodr : wxVhiceodrs) {
                if (i > 0) {
                    recordOrder(wxvhiceodr, OrderOperation.MODIFY_AMOUNT);
                }
            }
        }
        return i;
    }

    /**
     * 批量删除租车订单实例
     *
     * @param ids 需要删除的租车订单实例主键
     * @return 结果
     */
    @Override
    public int deleteWxVhiceodrByIds(Long[] ids) {
        return wxVhiceodrMapper.deleteWxVhiceodrByIds(ids);
    }

    /**
     * 删除租车订单实例信息
     *
     * @param id 租车订单实例主键
     * @return 结果
     */
    @Override
    public int deleteWxVhiceodrById(Long id) {
        return wxVhiceodrMapper.deleteWxVhiceodrById(id);
    }

    /**
     * 实现租车订单支付结构生成
     *
     * @param wxVhiceodrDto 订单信息
     * @return 微信签名
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, String> generateOrder(WxVhiceodrDto wxVhiceodrDto) throws Exception {
        //校验订单是否可以正常创建
        checkOrder(wxVhiceodrDto);
        // 生成订单编号
        wxVhiceodrDto.setOrderNum(getGenOrderNum());
        // 自由订单来源 1 携程 2 哈罗 3 悟空 4 自有订单
        wxVhiceodrDto.setOrderCategorize(4L);
        // 创建微信支付并保存支付信息
        Map<String, String> payMap = this.genWxOrder(wxVhiceodrDto);
        if (payMap == null) {
            throw new OrderException(OrderConstant.PAYMENT_SIGNATURE_ERROR);
        }
        payMap.put("orderNum", wxVhiceodrDto.getOrderNum());
        // 将开始时间和结束时间存入到预计开始与结束时间
        wxVhiceodrDto.setBookStartTime(wxVhiceodrDto.getStartTime());
        wxVhiceodrDto.setBookEndTime(wxVhiceodrDto.getEndTime());
        OrderOperation operation = OrderOperation.GENERATE_ORDER;
        // 记录操作
        recordOrder(wxVhiceodrDto, operation);
        // 记录操作订单
        wxVhiceodrDto.setStatus(operation);
        wxVhiceodrDto.setCreateTime(DateUtils.getNowDate());

        wxVhiceodrMapper.insertWxVhiceodr(wxVhiceodrDto);
//        // 生成违章信息
//        imsVehViolationService.generateVehViolation(wxVhiceodrDto);
        // 查询车辆空闲状态改为租用
        // 查询车辆信息
//        ImsYzzcSunGoods imsYzzcSunGoods = imsYzzcSunGoodsService.selectImsYzzcSunGoodsById(wxVhiceodrDto.getCid());
//        if (imsYzzcSunGoods.getStatus() == 1) {
//            // 为空闲状态则将车辆数据改为租用
//            imsYzzcSunGoods.setId(wxVhiceodrDto.getId());
//            imsYzzcSunGoods.setStatus(2);
//            imsYzzcSunGoodsService.updateImsYzzcSunGoods(imsYzzcSunGoods);
//            // 添加订单
//            // 创建公用表单
//        } else {
//            throw new RuntimeException("车辆已经被租用");
//        }
        return payMap;
    }

    /**
     * 校验是否可以生成订单
     * @param wxVhiceodr 需要生成的订单订单
     */
    private void checkOrder(WxVhiceodr wxVhiceodr) {
        if (wxVhiceodr.getTotalMoney().compareTo(BigDecimal.ZERO) <= 0) {
            throw new OrderException(OrderConstant.ILLEGAL_AMOUNT);
        }
        if (wxVhiceodr.getStartTime().compareTo(wxVhiceodr.getEndTime()) >= 0) {
            throw new OrderException(OrderConstant.ILLEGAL_TIME);
        }
        // 查询该用户是否有未支付订单
        WxVhiceodrDto wxVhiceodrQuery = new WxVhiceodrDto();
        wxVhiceodrQuery.setOpenId(wxVhiceodr.getOpenId());
        wxVhiceodrQuery.setStatus(OrderOperation.GENERATE_ORDER);
        List<WxVhiceodrVo> wxVhiceodrs = wxVhiceodrMapper.selectWxVhiceodrList(wxVhiceodrQuery);
        if (wxVhiceodrs.size() > 0) {
            throw new OrderException(OrderConstant.ORDER_UNPAID, wxVhiceodrs.get(0).getOrderNum());
        }
        wxVhiceodrQuery = new WxVhiceodrDto();
        wxVhiceodrQuery.setCid(wxVhiceodr.getCid());
        wxVhiceodrQuery.setStartTime(wxVhiceodr.getStartTime());
        wxVhiceodrQuery.setEndTime(wxVhiceodr.getEndTime());

        // 校验查询在订单时间内是否有车辆租用
        if (wxVhiceodrMapper.isRentVehicle(wxVhiceodr.getCid(), wxVhiceodr.getStartTime(), wxVhiceodr.getEndTime())) {
            throw new OrderException(OrderConstant.VEHICLE_RENT, wxVhiceodr.getOrderNum());
        }
    }

    /**
     * @return 生成的订单号
     */
    private String getGenOrderNum() {
        // 生成微信支付订单
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        String uid_pfix = format.format(new Date());
        String randomNum = RandomStringUtils.randomNumeric(10).toString();
        return uid_pfix + randomNum;
    }
    private String getGenOrderNum(int defaultNumber) {
        // 生成微信支付订单
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        String uid_pfix = format.format(new Date());
        String randomNum = RandomStringUtils.randomNumeric(defaultNumber).toString();
        return uid_pfix + randomNum;
    }


    private Map<String, String> genWxOrder(WxVhiceodrDto wxVhiceodr) {
        Map<String, String> req = new HashMap<String, String>();
        String nonceStr = WXPayUtil.generateNonceStr();

        req.put("appid", RuoYiConfig.getAppId());
        // 商户号
        req.put("mch_id", RuoYiConfig.getMchId());
        // 32位随机字符串
        req.put("nonce_str", nonceStr);
        req.put("body", wxVhiceodr.getCarName());
        req.put("out_trade_no", wxVhiceodr.getOrderNum());
        req.put("spbill_create_ip", wxVhiceodr.getIp());
        // 回调地址+携带的返回参数  domain 为配置的域名[不可为ip地址]
        //req.put("notify_url", "http://tqq63r.natappfree.cc/wechat/vehorder/notify-order-wx" + wxVhiceodr.getOrderNum());
        req.put("notify_url", RuoYiConfig.getDomain()+"/wechat/vehorder/notify-order-wx/" + wxVhiceodr.getOrderNum());
        // 交易类型
        req.put("trade_type", "JSAPI");
        req.put("openid", wxVhiceodr.getOpenId());
        req.put("profit_sharing", "Y");
        req.put("total_fee", String.valueOf(MoneyUtils.yuanToFen(String.valueOf(wxVhiceodr.getTotalMoney()))));
        try {
            req.put("sign", WXPayUtil.generateSignature(req, RuoYiConfig.getApiKey(), WXPayConstants.SignType.MD5));
            String xmlBody = WXPayUtil.generateSignedXml(req, RuoYiConfig.getApiKey());
            System.err.println(String.format("微信支付预下单请求 xml 格式:\n%s", xmlBody));
            String result = WxChatPayCommonUtil.httpsRequest(WXPayConstants.UNIFIEDORDER_URL, "POST", xmlBody);
            System.err.println(String.format("%s", result));
            Map<String, String> WxResultMap = WXPayUtil.xmlToMap(result);
            if (ObjectUtils.isNotEmpty(WxResultMap.get("return_code")) && WxResultMap.get("return_code").equals("SUCCESS")) {
                if (WxResultMap.get("result_code").equals("SUCCESS")) {
                    Map<String,String > signMap=new HashMap<String,String>();
                    signMap.put("appId", RuoYiConfig.getAppId());
                    signMap.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
                    signMap.put("nonceStr", nonceStr);
                    signMap.put("signType", "MD5");
                    signMap.put("package", "prepay_id=" + WxResultMap.get("prepay_id"));
                    System.out.println("cao:"+WXPayUtil.generateSignature(signMap, RuoYiConfig.getApiKey(), WXPayConstants.SignType.MD5));;
                    //二次签名
                    signMap.put("paySign", WechatPayUtil.generateSign(signMap, RuoYiConfig.getApiKey()));
                    return signMap;
                }
            }
        } catch (OrderException orderException) {
            throw new OrderException(OrderConstant.VEHICLE_RENT);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WxVhiceodr generateBaseOrder(WxVhiceodr wxVhiceodr) {
        //生成订单号
        wxVhiceodr.setOrderNum(getGenOrderNum());
        // 该操作为生成订单操作
        OrderOperation operation = OrderOperation.CREATE_ORDER;
        // 记录订单状态变化操作，需要在改变状态前记录从原始状态变为改变后状态记录
        recordOrder(wxVhiceodr, operation);
        // 设置成待接单状态
        wxVhiceodr.setStatus(operation);
        // 查询车辆信息
        ImsYzzcSunGoods imsYzzcSunGoods = imsYzzcSunGoodsService.selectImsYzzcSunGoodsById(wxVhiceodr.getCid());
        // 查询车辆空闲状态改为租用
        if (imsYzzcSunGoods.getStatus() == 1) {
            // 为空闲状态则将车辆数据改为租用
            imsYzzcSunGoods.setId(wxVhiceodr.getId());
            imsYzzcSunGoods.setStatus(2);
            imsYzzcSunGoodsService.updateImsYzzcSunGoods(imsYzzcSunGoods);
            // 添加订单
            wxVhiceodrMapper.insertWxVhiceodr(wxVhiceodr);
            // 创建公用表单
            createForm(wxVhiceodr);
        } else {
            throw new RuntimeException("车辆已经被租用");
        }
        return wxVhiceodr;
    }

    @Override
    public WxVhiceodr staffOperationOrders(WxVhiceodr wxVhiceodr) {
        OrderOperation lastOperation = OrderOperation.getInstance(wxVhiceodr.getStatus());
        OrderOperation operation;
        switch (lastOperation) {
            case PAYMENT_ORDER:
                operation = OrderOperation.ACCEPT_ORDERS;
                break;
            case USE_LOADING:
            case CONTINUED_ORDER:
                operation = OrderOperation.ACCEPT_RETRIEVE_ORDERS;
                break;
            // 员工拒绝接单情况
            case ACCEPT_ORDERS:
                operation = OrderOperation.PAYMENT_ORDER;
                break;
            // 员工拒绝接单情况
            case ACCEPT_RETRIEVE_ORDERS:
                operation = OrderOperation.CONTINUED_ORDER;
                break;
            default:
                throw new RuntimeException("违规的员工订单操作");
        }
        // 创建空白模版，放置借此接口修改数据
        recordOrder(wxVhiceodr, operation);
        WxVhiceodr wxVhiceodr1 = new WxVhiceodr();
        wxVhiceodr1.setStatus(operation);
        wxVhiceodr1.setId(wxVhiceodr.getId());
        wxVhiceodr1.setUpdateTime(DateUtils.getNowDate());
        wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr1);
        return wxVhiceodr;
    }

    @Override
    public List<WxVhiceodrOeaiRcrVo> selectWxVhiceodrRecordList(String vo_num) {
        return wxVhiceodrRecordMapper.selectWxVhiceodrRecordLine(vo_num);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int acceptOrders(WxVhiceodr wxVhiceodr) {
        // 修改车辆状态，标识车辆已被租用
        ImsYzzcSunGoods imsYzzcSunGoods = new ImsYzzcSunGoods();
        imsYzzcSunGoods.setId(wxVhiceodr.getCid());
        imsYzzcSunGoods.setStatus(2);
        imsYzzcSunGoodsService.updateImsYzzcSunGoods(imsYzzcSunGoods);

        // 查询数据库判断是否已被抢单
        WxVhiceodr wxVhiceodrSelect = selectWxVhiceodrByNum(wxVhiceodr.getOrderNum());
        OrderOperation operation = OrderOperation.getInstance(wxVhiceodrSelect.getStatus());
        // 接单判断订单是否已经被接单或者抢单了
        if (operation != OrderOperation.PAYMENT_ORDER && operation != OrderOperation.USE_EXPIRE) {
            throw new OrderException(OrderConstant.ORDER_HAS_ROBBED);
        }
        // 创建新模版进行数据更新
        WxVhiceodr wxVhiceodrUpdate = new WxVhiceodr();
        wxVhiceodrUpdate.setId(wxVhiceodrSelect.getId());
        Long userId = SecurityUtils.getLoginUser().getUserId();
        // 接单人id保存到订单中
        wxVhiceodrUpdate.setUid(userId);
        // 判断是否为送车订单（送车订单一般为支付了金额的订单）
        if (operation==OrderOperation.PAYMENT_ORDER) {
            recordOrder(wxVhiceodr, OrderOperation.ACCEPT_ORDERS);
            // 记录真实开始订单时间
            wxVhiceodrUpdate.setStartTime(DateUtils.getNowDate());
            wxVhiceodrUpdate.setStatus(OrderOperation.ACCEPT_ORDERS);

            // 将提成表单关联用户id变更为当前接单人id
            WxFormRecord wxFormRecord = new WxFormRecord();
            wxFormRecord.setId(wxVhiceodr.getPickFormId());
            wxFormRecord.setUid(userId);
            wxFormRecordService.updateOnlWxFormRecord(wxFormRecord);

            // 判断是否为收车订单（收车订单为为用用户提前还车或订单超过预期时间的订单）
        } else {
            wxVhiceodr.setEndTime(DateUtils.getNowDate());
            // 记录订单操作
            recordOrder(wxVhiceodr, OrderOperation.ACCEPT_RETRIEVE_ORDERS);
            wxVhiceodrUpdate.setStatus(OrderOperation.ACCEPT_RETRIEVE_ORDERS);
            // 记录真实订单结束时间
            wxVhiceodrUpdate.setEndTime(DateUtils.getNowDate());

            // 将提成表单关联用户id变更为当前接单人id
            WxFormRecord wxFormRecord = new WxFormRecord();
            wxFormRecord.setId(wxVhiceodr.getReturnFormId());
            wxFormRecord.setUid(userId);
            wxFormRecordService.updateOnlWxFormRecord(wxFormRecord);
        }
        return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodrUpdate);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int assignOrders(AssignOrders assignOrders) {


        OrderOperation lastOrderOperation = OrderOperation.getInstance(assignOrders.getOrderStatus());
        // 创建修改模版类
        WxVhiceodr wxVhiceodr1 = wxVhiceodrMapper.selectWxVhiceodrByNum(assignOrders.getOrderNum());
        wxVhiceodr1.setOrderNum(assignOrders.getOrderNum());
        wxVhiceodr1.setId(assignOrders.getOrderId());
        wxVhiceodr1.setUpdateTime(DateUtils.getNowDate());
        wxVhiceodr1.setRemark(assignOrders.getRemark());
        // 执行操作前记录订单操作记录
        recordOrder(wxVhiceodr1, OrderOperation.ASSIGN_ORDERS);

        // 修改车辆状态，改为已租
        ImsYzzcSunGoods imsYzzcSunGoods = new ImsYzzcSunGoods();
        imsYzzcSunGoods.setId(wxVhiceodr1.getCid());
        imsYzzcSunGoods.setStatus(2);
        imsYzzcSunGoodsService.updateImsYzzcSunGoods(imsYzzcSunGoods);

        // 创建需要修改的表单对象
        WxFormRecord wxFormRecord = new WxFormRecord();
        wxFormRecord.setUid(-1L);
        OrderOperation orderOperation;
        switch (lastOrderOperation) {
            case PAYMENT_ORDER:
            case CREATE_ORDER:
            case ACCEPT_ORDERS:// 员工接单后更换接单对象
                orderOperation = OrderOperation.ACCEPT_ORDERS;
                wxFormRecord.setId(wxVhiceodr1.getPickFormId());
                break;
            case CONTINUED_ORDER:  // 员工接单后更换接单对象
            case USE_LOADING:
            case ACCEPT_RETRIEVE_ORDERS:
                orderOperation = OrderOperation.ACCEPT_RETRIEVE_ORDERS;
                wxFormRecord.setId(wxVhiceodr1.getReturnFormId());
                break;
            default:
                throw new RuntimeException("指派错误,当前订单无法进行指派");
        }
        // 保存修改状态记录
        wxVhiceodr1.setStatus(orderOperation);

        // 将对应表单置空
        wxFormRecordService.updateWxFormRecord(wxFormRecord);

        // 保存修改订单
        return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr1);
    }

    @Override
    public Map<String, Integer> selectSumQuantity(Long deptId) {
        List<SumQuantityVo> sumQuantityVos = wxVhiceodrMapper.selectSumQuantityGroupStatus(deptId);

        Map<String, Integer> dataMap = new HashMap<>();
        //即将到期
        dataMap.put("expirationSoon", 0);
        // 订单总数
        dataMap.put("totalOrder", 0);
        // 待送车
        dataMap.put("carToBeSentTotal", 0);
        // 到期
        dataMap.put("dueTotal", 0);
        // 待结算
        dataMap.put("toSettlementTotal", 0);
        // 已取车
        dataMap.put("usingTotal", 0);
        // 已接单
        dataMap.put("inDeliveryTotal", 0);
        //还车中
        dataMap.put("returnCarTotal", 0);
        //已完成
        dataMap.put("completeTotal", 0);
        //待支付
        dataMap.put("toBePaidTotal", 0);


        WxVhiceodrDto wxVhiceodrDto = new WxVhiceodrDto();
        wxVhiceodrDto.setDeptId(deptId);
        //查询总订单数量
        dataMap.put("totalOrder", wxVhiceodrMapper.selectSumQuantity(wxVhiceodrDto));
        //查询即将过期数量
        wxVhiceodrDto.setExpiringSoon(true);
        wxVhiceodrDto.setStatus(OrderOperation.USE_LOADING);
        dataMap.put("expirationSoon", wxVhiceodrMapper.selectSumQuantity(wxVhiceodrDto));
        // 查询过期数量
//        wxVhiceodrDto.setExpir(null);
//        wxVhiceodrDto.setStatus(OrderOperation.USE_LOADING);
//        wxVhiceodrDto.setExpiringSoon(true);
//        dataMap.put("dueTotal", wxVhiceodrMapper.selectSumQuantity(wxVhiceodrDto));

        for (SumQuantityVo sumQuantityVo : sumQuantityVos) {
            switch (OrderOperation.getInstance(sumQuantityVo.getStatus())) {
                case PAYMENT_ORDER:
                    //case CREATE_ORDER:
                    dataMap.put("carToBeSentTotal", sumQuantityVo.getCount());
                    break;
                case GENERATE_ORDER:
                    dataMap.put("toBePaidTotal", sumQuantityVo.getCount());
                    break;
                case USE_LOADING:
                case CONTINUED_ORDER:
                    dataMap.put("usingTotal", dataMap.get("usingTotal") + sumQuantityVo.getCount());
                    break;
                case USE_EXPIRE:
                    dataMap.put("dueTotal", sumQuantityVo.getCount());
                    break;
                case ACCEPT_ORDERS:
                    // 已接单
                    dataMap.put("inDeliveryTotal", sumQuantityVo.getCount());
                    break;
                case ACCEPT_RETRIEVE_ORDERS:
                    dataMap.put("returnCarTotal", sumQuantityVo.getCount());
                    break;
                case CONFIRM_COMPLETION:
                    dataMap.put("completeTotal", sumQuantityVo.getCount());
                    break;
                case RECEIVE_LOADING:
                    dataMap.put("toSettlementTotal", sumQuantityVo.getCount());
            }
        }
        return dataMap;
    }

    /**
     * 订单退款接口
     * @param wxVhiceodrDto
     * @return 退款接口
     */
    @Override
    public int refundMoney(WxVhiceodrDto wxVhiceodrDto) {
        //构建参数
        Map<String, String> dataMap = new HashMap<>();
        dataMap.put("appid",wechatCustomerConfig.getAppId());
        dataMap.put("mch_id",wechatCustomerConfig.getMchId());
        //自行实现该随机串
        dataMap.put("nonce_str", WXPayUtil.generateNonceStr());
        dataMap.put("out_trade_no",wxVhiceodrDto.getOrderNum());
        dataMap.put("out_refund_no",wxVhiceodrDto.getOrderNum()+getGenOrderNum(4));
        dataMap.put("total_fee",String.valueOf(MoneyUtils.yuanToFen(String.valueOf(wxVhiceodrDto.getTotalMoney()))));
        dataMap.put("refund_fee",String.valueOf(MoneyUtils.yuanToFen(String.valueOf(wxVhiceodrDto.getRefundMoney()))));
        dataMap.put("refund_desc","退款");
        //生成签名
        String sign = null;
        try {
            sign = WXPayUtil.generateSignature(dataMap, wechatCustomerConfig.getApiKey());
            dataMap.put("sign", sign);
            //map数据转xml
            String xmlString =WXPayUtil.mapToXml(dataMap);
            //记录订单退款
            recordOrder(wxVhiceodrDto, OrderOperation.REFUND_ORDER);
            //发起退款
            String jsonStr=doRefund(wechatCustomerConfig.getMchId(), WeChatPayUrl.Refund, xmlString);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return 0;
    }


    /**
     * 保存车辆订单的操作记录
     *
     * @param wxVhiceodr 订单实例
     * @param markFlag   操作记录标识
     */
    public void recordOrder(WxVhiceodr wxVhiceodr, OrderOperation markFlag) {
        WxVhiceodrOeaiRcr wxVhiceodrRecord = new WxVhiceodrOeaiRcr();
        wxVhiceodrRecord.setStatus(wxVhiceodr.getStatus());
        wxVhiceodrRecord.setVoNum(wxVhiceodr.getOrderNum());
        wxVhiceodrRecord.setMarkFlag(markFlag.getMakeFlag());
        wxVhiceodrRecord.setRemark(wxVhiceodr.getRemark());
        wxVhiceodrRecord.setCreateTime(new Date());
        wxVhiceodrRecord.setDelFlag("0");
        switch (markFlag) {
            case GENERATE_ORDER:
            case PAYMENT_ORDER:
            case USE_LOADING:
            case CONTINUED_ORDER:
                // 这两个操作用户都是微信租车顾客产生
                wxVhiceodrRecord.setuType(1);
                break;
            default:
                // 获取当前用户信息
                try{
                    wxVhiceodrRecord.setuType(0);
                    wxVhiceodrRecord.setUid(SecurityUtils.getLoginUser().getUserId());
                }catch (Exception e){
                    // 微信用户没有登录用户信息，通过报错判断车辆状态
                    wxVhiceodrRecord.setuType(1);
                }
        }
        wxVhiceodrRecordMapper.insertWxVhiceodrRecord(wxVhiceodrRecord);
    }

    /**
     * 支付成功后调用方法
     *
     * @param orderNum 订单编号
     */
    @Override
    @Transactional
    public void paymentSuccessOrder(String orderNum) {
        WxVhiceodr wxVhiceodr= wxVhiceodrMapper.selectWxVhiceodrByNum(orderNum);
        // 记录操作
        recordOrder(wxVhiceodr, OrderOperation.PAYMENT_ORDER);
        // 修改订单状态
        wxVhiceodr.setStatus(OrderOperation.PAYMENT_ORDER);
        //创建表单
        createForm(wxVhiceodr);
    }

    @Override
    public Map<String, String> payOrder(WxVhiceodrDto wxVhiceodrDto) {
        return genWxOrder(wxVhiceodrDto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int abandonOrder(WxVhiceodr order) {
        // 记录订单操作
        recordOrder(order, OrderOperation.ABANDON_ORDER);
        WxVhiceodr wxVhiceodr = new WxVhiceodr();
        wxVhiceodr.setId(order.getId());
        // 记录员工弃单
        WxFormRecord wxFormRecord;
        // 获取当前状态
        OrderOperation operation = OrderOperation.getInstance(order.getStatus());

        //  租车有两种接单 （送车订单/收车订单）方式，通过status区分送车或收车订单
        //  orderType 判断租车还是包车字段，租车为0，包车为1。通过订单状态判断执行方法
        if (operation == OrderOperation.ACCEPT_ORDERS) {
            if (order.getOrderType() == 0L) {
                // 修改订单上回状态
                wxVhiceodr.setStatus(OrderOperation.PAYMENT_ORDER);

                wxFormRecord = wxFormRecordService.selectWxFormRecordById(order.getPickFormId());
            } else if (order.getOrderType() == 1L) {
                // 修改订单上回状态
                wxVhiceodr.setStatus(OrderOperation.CREATE_ORDER);
                wxFormRecord = wxFormRecordService.selectWxFormRecordById(order.getReturnFormId());
            } else {
                throw new RuntimeException("订单错误，当前订单为非法订单");
            }
        } else if (operation == OrderOperation.ACCEPT_RETRIEVE_ORDERS && order.getOrderType() == 0L) {
            // 修改订单上回状态
            wxVhiceodr.setStatus(OrderOperation.USE_EXPIRE);
            wxFormRecord = wxFormRecordService.selectWxFormRecordById(order.getPickFormId());
        } else {
            throw new RuntimeException("订单错误，当前订单为非法订单");
        }
        // 将值置空，标识提成为空
        wxFormRecord.setUid(null);
        wxFormRecordService.updateWxFormRecord(wxFormRecord);
        return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int refuseOrder(WxVhiceodrDto wxVhiceodr) {
        recordOrder(wxVhiceodr, OrderOperation.REJECT_ORDERS);
        wxVhiceodr.setStatus(OrderOperation.REJECT_ORDERS);
        refundMoney(wxVhiceodr);
        // 提成表单设置为
        Long[] ids = new Long[]{wxVhiceodr.getPickFormId(), wxVhiceodr.getReturnFormId()};
        // 删除提成表单
        wxFormRecordService.deleteWxFormRecordByIds(ids);
        return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int pickUpCar(WxVhiceodr wxVhiceodr) {
        // 订单非法访问
        if (!wxVhiceodr.getStatus().equals(OrderOperation.ACCEPT_ORDERS.getMakeFlag())) {
            throw new OrderException(OrderConstant.ILLEGAL_ACCESS);
        }
        recordOrder(wxVhiceodr, OrderOperation.USE_LOADING);
        WxVhiceodr wxVhiceodr1 = new WxVhiceodr();
        wxVhiceodr1.setId(wxVhiceodr.getId());
        wxVhiceodr1.setStatus(OrderOperation.USE_LOADING);

        return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr1);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int returnCar(WxVhiceodr wxVhiceodr) {
        // 订单非法访问
        if (!wxVhiceodr.getStatus().equals(OrderOperation.ACCEPT_RETRIEVE_ORDERS.getMakeFlag())) {
            throw new OrderException(OrderConstant.ILLEGAL_ACCESS);
        }
        recordOrder(wxVhiceodr, OrderOperation.RECEIVE_LOADING);
        // 修改车辆状态，标识车辆已被租用
        ImsYzzcSunGoods imsYzzcSunGoods = new ImsYzzcSunGoods();
        imsYzzcSunGoods.setId(wxVhiceodr.getCid());
        imsYzzcSunGoods.setStatus(1);
        imsYzzcSunGoodsService.updateImsYzzcSunGoods(imsYzzcSunGoods);
        // 修改订单状态
        WxVhiceodr wxVhiceodr1 = new WxVhiceodr();
        wxVhiceodr1.setId(wxVhiceodr.getId());
        wxVhiceodr1.setStatus(OrderOperation.RECEIVE_LOADING);
        return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr1);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveUpdate(WxVhiceodr wxVhiceodr) {
        OrderOperation operation = OrderOperation.getInstance(wxVhiceodr.getStatus());
        switch (operation) {
            case ACCEPT_RETRIEVE_ORDERS:
            case ACCEPT_ORDERS:
            case RECEIVE_LOADING:
                recordOrder(wxVhiceodr, OrderOperation.MODIFY_ORDER_INFO);
                WxVhiceodr wxVhiceodr1 = new WxVhiceodr();
                wxVhiceodr1.setId(wxVhiceodr.getId());
                // 还车信息
                wxVhiceodr1.setReturnKilometers(wxVhiceodr.getReturnKilometers());
                wxVhiceodr1.setReturnDepartureFuel(wxVhiceodr.getReturnDepartureFuel());
                wxVhiceodr1.setReturnVehUrl(wxVhiceodr.getReturnVehUrl());
                wxVhiceodr1.setReturnVehvideoUrl(wxVhiceodr.getReturnVehvideoUrl());
                // 送车信息
                wxVhiceodr1.setPickUpCardUrl(wxVhiceodr.getPickUpCardUrl());
                wxVhiceodr1.setPickUpKilometers(wxVhiceodr.getPickUpKilometers());
                wxVhiceodr1.setPickUpDepartureFuel(wxVhiceodr.getPickUpDepartureFuel());
                wxVhiceodr1.setPickUpVehUrl(wxVhiceodr.getPickUpVehUrl());
                wxVhiceodr1.setPickUpVideoUrl(wxVhiceodr.getPickUpVideoUrl());
                wxVhiceodr1.setRemark(wxVhiceodr.getRemark());
                // 售后维修信息
                wxVhiceodr1.setRepair(wxVhiceodr.getRepair());
                wxVhiceodr1.setRepairAmount(wxVhiceodr.getRepairAmount());
                wxVhiceodr1.setOwedAmount(wxVhiceodr.getOwedAmount());
                wxVhiceodr1.setVehInvoicePic(wxVhiceodr.getVehInvoicePic());
                return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr1);
            default:
                throw new OrderException(OrderConstant.ILLEGAL_ACCESS);
        }
    }

    @Override
    public int orderSettlement(WxVhiceodr wxVhiceodr) {
        if (wxVhiceodr.getStatus().equals(OrderOperation.RECEIVE_LOADING.getMakeFlag())) {
            recordOrder(wxVhiceodr, OrderOperation.CONFIRM_COMPLETION);
            WxVhiceodr wxVhiceodr1 = new WxVhiceodr();
            wxVhiceodr1.setId(wxVhiceodr.getId());
            wxVhiceodr1.setStatus(OrderOperation.CONFIRM_COMPLETION);
            wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr1);
        }
        return 0;
    }

    @Override
    public int rentalDepositRefund(WxVhiceodr wxVhiceodr) {
        if (wxVhiceodr.getIsReturnVehdeposit()==0){
            recordOrder(wxVhiceodr,OrderOperation.REFUND_RENTAL_DEPOSIT);
            // 退还租车押金金额
            BigDecimal decimal= wxVhiceodr.getDepositMoney().subtract(wxVhiceodr.getRefundMoney()).subtract(wxVhiceodr.getOwedAmount());
            WxVhiceodrDto wxVhiceodrDto = new WxVhiceodrDto();
            wxVhiceodrDto.setId(wxVhiceodr.getId());
            wxVhiceodrDto.setOrderNum(wxVhiceodr.getOrderNum());
            wxVhiceodrDto.setTotalMoney(wxVhiceodr.getTotalMoney());
            wxVhiceodrDto.setRefundMoney(decimal);
            if (decimal.compareTo(BigDecimal.ZERO)>0){
                // 请求微信退还金额
                refundMoney(wxVhiceodrDto);
            }
            wxVhiceodr.setIsReturnVehdeposit(1);
            return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr);
        }
        return 0;
    }

    @Override
    public int violationDepositRefund(WxVhiceodr wxVhiceodr) {
        if (wxVhiceodr.getIsReturnViodeposit()==0){
            recordOrder(wxVhiceodr,OrderOperation.REFUND_VIOLATION_DEPOSIT);
            WxVhiceodrDto wxVhiceodrDto = new WxVhiceodrDto();
            wxVhiceodrDto.setId(wxVhiceodr.getId());
            wxVhiceodrDto.setOrderNum(wxVhiceodr.getOrderNum());
            wxVhiceodrDto.setTotalMoney(wxVhiceodr.getTotalMoney());
            wxVhiceodrDto.setRefundMoney(wxVhiceodr.getViolationDeposit());
            refundMoney(wxVhiceodrDto);
            wxVhiceodr.setIsReturnViodeposit(1);
            return wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodr);
        }
        return 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int refundOrder(WxVhiceodr wxVhiceodr) {
        // 修改订单状态
        recordOrder(wxVhiceodr, OrderOperation.REFUND_ORDER);
        WxVhiceodrDto wxVhiceodrDto = new WxVhiceodrDto();
        wxVhiceodrDto.setId(wxVhiceodr.getId());
        wxVhiceodrDto.setStatus(OrderOperation.REFUND_ORDER);
        wxVhiceodrDto.setRemark(wxVhiceodr.getRemark());
        int count = wxVhiceodrMapper.updateWxVhiceodr(wxVhiceodrDto);

        ImsYzzcSunGoods imsYzzcSunGoods = new ImsYzzcSunGoods();
        imsYzzcSunGoods.setId(wxVhiceodr.getCid());
        imsYzzcSunGoods.setStatus(1);
        imsYzzcSunGoodsService.updateImsYzzcSunGoods(imsYzzcSunGoods);

        wxVhiceodrDto.setOrderNum(wxVhiceodr.getOrderNum());
        wxVhiceodrDto.setTotalMoney(wxVhiceodr.getTotalMoney());
        wxVhiceodrDto.setRefundMoney(wxVhiceodr.getTotalMoney());
        refundMoney(wxVhiceodrDto);
        return count;
    }


    /**
     *
     * @param mchId 商户ID
     * @param url 请求URL
     * @param data 退款参数
     * @return
     * @throws Exception
     */
    private String doRefund(String mchId, String url, String data) throws Exception {
        /**
         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
         */
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        //FileInputStream读取本地证书文件
        BufferedInputStream inputStream = FileUtil.getInputStream(RuoYiConfig.getProfile()+"/apiclient_cert.p12");
        System.out.println(inputStream.available());
        try {
            //这里写密码..默认是你的MCHID
            keyStore.load(inputStream, mchId.toCharArray());
        } finally {
            inputStream.close();
        }
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, mchId.toCharArray())
                .build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();
        try {
            HttpPost httpost = new HttpPost(url);
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                //接受到返回信息
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
                return jsonStr;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}

